using FytSoa.Application.Crm.Param;
using FytSoa.Common.Enum;
using FytSoa.Common.Extensions;
using FytSoa.Domain.Crm;
using FytSoa.Sugar;
using FytSoa.Common.Utils;
using FytSoa.Common.Param;
using FytSoa.Common.Result;
using FytSoa.Domain.Hr;
using FytSoa.Domain.Sys;
using Mapster;
using Microsoft.AspNetCore.Mvc;
using SqlSugar;

namespace FytSoa.Application.Crm;

/// <summary>
/// 工单服务接口
/// </summary>
[ApiExplorerSettings(GroupName = "v7")]
public class CrmWocOrderService : IApplicationService 
{
    private readonly SugarRepository<CrmWocOrder> _thisRepository;
    private readonly SugarRepository<SysMessage> _messageRepository;
    private readonly SugarRepository<SysAdmin> _adminRepository;
    private readonly SugarRepository<HrEmployee> _employeeRepository;
    private readonly SugarRepository<CrmWocLog> _logRepository;
    private readonly CrmWocLogService _logService;
    public CrmWocOrderService(SugarRepository<CrmWocOrder> thisRepository
        ,SugarRepository<SysMessage> messageRepository
        ,SugarRepository<SysAdmin> adminRepository
        ,SugarRepository<HrEmployee> employeeRepository
        ,SugarRepository<CrmWocLog> logRepository
        ,CrmWocLogService logService)
    {
        _thisRepository = thisRepository;
        _messageRepository = messageRepository;
        _adminRepository = adminRepository;
        _employeeRepository = employeeRepository;
        _logRepository = logRepository;
        _logService = logService;
    }
    
    /// <summary>
    /// 查询所有——分页
    /// </summary>
    /// <param name="param"></param>
    /// <returns></returns>
    public async Task<PageResult<CrmWocOrderDto>> GetPagesAsync(CrmWocOrderSearchParam param)
    {
        var query = await _thisRepository.AsQueryable()
            .WhereIF(!string.IsNullOrEmpty(param.Key),m=>m.Title.Contains(param.Key) || m.Number.Contains(param.Key) || 
                                                         SqlFunc.Subqueryable<CrmCustomer>().Where(it=>it.Id==m.CustomerId && it.Name.Contains(param.Key) || it.Tel.Contains(param.Key)).Any())
            .WhereIF(!string.IsNullOrEmpty(param.Status) && param.Status!="0",m=>m.Status==int.Parse(param.Status))
            .WhereIF(!string.IsNullOrEmpty(param.IdArr),m=>param.IdArr.StrToListLong().Contains(m.Id))
            .WhereIF(param.Level!=0,m=>m.Level==param.Level)
            .WhereIF(param.Source!=0,m=>m.Source==param.Source)
            .WhereIF(param.TypeId!=0,m=>m.Type==param.TypeId)
            .WhereIF(param.CustomerId!=0,m=>m.CustomerId==param.CustomerId)
            .WhereIF(param.CustomerLevel!=0,m=>SqlFunc.Subqueryable<CrmCustomer>().Where(it=>it.Id==m.CustomerId && it.Level==param.CustomerLevel).Any())
            .WhereIF(param.UserId.Count>0,m=>param.UserId.Contains(m.LastProcessUserId))
            .Includes(m=>m.CustomerObj)
            .Includes(m=>m.SourceObj)
            .Includes(m=>m.LevelObj)
            .Includes(m=>m.TypeObj)
            .OrderByDescending(m=>m.Id)
            .ToPageAsync(param.Page, param.Limit);
        if (query.Items.Count==0)
        {
            return query.Adapt<PageResult<CrmWocOrderDto>>();
        }
        //处理最后一个处理人信息
        var userIdArr = query.Items.Select(item => item.LastProcessUserId).ToList();
        //根据用户查询信息
        var userList = await _adminRepository.AsQueryable()
            .Where(m => userIdArr.Contains(m.Id))
            .ToListAsync();
        var result=query.Adapt<PageResult<CrmWocOrderDto>>();
        foreach (var item in result.Items)
        {
            var user = userList.FirstOrDefault(m => m.Id == item.LastProcessUserId);
            if (user!=null)
            {
                item.LastUser = new CrmWocOrderDto.SendUserInfo()
                {
                    Id = user.Id,
                    Avatar = user.Avatar,
                    FullName = user.FullName
                };
            }
        }
        return result;
    }

    /// <summary>
    /// 根据主键查询
    /// </summary>
    /// <param name="id"></param>
    /// <returns></returns>
    [HttpGet("{id}")]
    public async Task<CrmWocOrderDto> GetAsync(long id)
    {
        var model = await _thisRepository.AsQueryable()
            .Includes(m => m.CustomerObj)
            .Includes(m => m.SourceObj)
            .Includes(m => m.LevelObj)
            .Includes(m => m.TypeObj)
            .FirstAsync(m => m.Id == id);
        
        var userIdArr = model.SendUser.Select(m => m.Id).ToList();
        var userList = await _employeeRepository.AsQueryable()
            .Where(m => userIdArr.Contains(m.Id))
            .Includes(m=>m.OrganizationObj)
            .ToListAsync();
        var result=model.Adapt<CrmWocOrderDto>();
        var list = new List<CrmWocOrderDto.SendUserInfo>();
        foreach (var item in result.SendUser)
        {
            var user = userList.FirstOrDefault(m => m.Id == item.Id);
            if (user!=null)
            {
                list.Add(new CrmWocOrderDto.SendUserInfo()
                {
                    Id = user.Id,
                    Avatar = user.Avatar,
                    FullName = user.Name,
                    Organization = user.OrganizationObj.Name,
                    Why = item.Why,
                    Files = item.Files,
                    CreateTime = item.CreateTime
                });
            }
        }
        result.SendProgressUser = list;
        return result;
    }

    /// <summary>
    /// 添加
    /// </summary>
    /// <param name="model"></param>
    /// <returns></returns>
    public async Task AddAsync(CrmWocOrderAdd model)
    {
        var number = string.Empty;
        var toDay = await _thisRepository.CountAsync(m=>SqlFunc.DateIsSame(m.CreateTime,DateTime.Now));
        number = toDay switch
        {
            < 10 => "00" + (toDay + 1),
            >= 10 and < 100 => "0" + (toDay + 1),
            _ => number
        };
        if (toDay>=99)
        {
            number = (toDay+1).ToString();
        }
        model.Number = "GO"+DateTime.Now.ToString("yyyyMMdd")+"-"+number;
        var addOrder = model.Adapt<CrmWocOrder>();
        addOrder.LastProcessUserId = addOrder.SendUser.Last().Id;
        var orderId=await _thisRepository.InsertReturnSnowflakeIdAsync(addOrder);
        
        //添加给派单人发送消息
        await _messageRepository.InsertAsync(new SysMessage()
        {
            ColumnId=orderId,
            UserId = model.SendUser.Last().Id,
            Types=MessageEnum.Order,
            Title="您有一个新的工单等您处理，请及时查看~"
        });
        
        //记录添加工单日志
        await _logService.AddAsync(new CrmWocLog() { OrderId = orderId,Status = 1});
    }

    /// <summary>
    /// 修改
    /// </summary>
    /// <param name="model"></param>
    /// <returns></returns>
    public async Task ModifyAsync(CrmWocOrderAdd model)
    {
        var updateOrder = model.Adapt<CrmWocOrder>();
        updateOrder.LastProcessUserId = updateOrder.SendUser.Last().Id;
        await _thisRepository.UpdateAsync(updateOrder);
        //添加给派单人发送消息
        await _messageRepository.InsertAsync(new SysMessage()
        {
            ColumnId=model.Id,
            UserId = model.SendUser.Last().Id,
            Types=MessageEnum.Order,
            Title="您有一个新的工单等您处理，请及时查看~"
        });
        
        //记录添加工单日志
        await _logService.AddAsync(new CrmWocLog() { OrderId = model.Id,Status = 2});
    }
    
    /// <summary>
    /// 增加驳回
    /// </summary>
    /// <param name="param"></param>
    /// <returns></returns>
    [UnitOfWork]
    public async Task AddRejectAsync(WocRejectParam param)
    {
        var order = await _thisRepository.GetFirstAsync(m => m.Id == param.Id);
        order.Reject = new CrmWocOrder.RejectJson()
        {
            Id = AppUtils.LoginId,
            Summary = param.Summary,
        };
        order.Status = 2;
        await _thisRepository.UpdateAsync(order);
        
        //记录添加工单日志
        await _logService.AddAsync(new CrmWocLog() { OrderId = order.Id,Status = 6});
    }
    
    /// <summary>
    /// 添加派单人-流转到下一级
    /// </summary>
    /// <param name="model"></param>
    /// <returns></returns>
    [UnitOfWork]
    public async Task AddUserAsync(CrmWocSendUser model)
    {
        var order = await _thisRepository.GetByIdAsync(model.OrderId);

        //添加给派单人发送消息
        await _messageRepository.InsertAsync(new SysMessage()
        {
            ColumnId=order.Id,
            UserId = model.Id,
            Types=MessageEnum.Order,
            Title="【流转】您有一个新的工单等您处理，请及时查看~"
        });
       
        order.SendUser.Add(model.Adapt<CrmWocOrder.SendUserProgress>());
        order.Status = 1;
        order.LastProcessUserId = model.Id;
        await _thisRepository.UpdateAsync(order);
        
        //记录添加工单日志
        await _logService.AddAsync(new CrmWocLog() { OrderId = order.Id,Status = 3});
        
    }
    
    /// <summary>
    /// 接单接口  需要填写处理限时
    /// </summary>
    /// <param name="model"></param>
    /// <returns></returns>
    public async Task ModifyAcceptAsync(CrmWocAcceptOrder model)
    {
        await _thisRepository.UpdateAsync(m=>new CrmWocOrder()
        {
            Status = 2,
            TimeLimit = model.TimeLimit,
            UpdateTime = DateTime.Now
        },m=>m.Id==model.Id);
        
        //记录添加工单日志
        await _logService.AddAsync(new CrmWocLog() { OrderId = model.Id,Status = 4});
    }
    
    /// <summary>
    /// 修改订单状态  1=待接收  2=处理中  3=待审核  4=已完成 5=已关闭
    /// </summary>
    /// <param name="model"></param>
    /// <returns></returns>
    public async Task ModifyStatusAsync(CrmWocUpdateStatus model)
    {
        var order = await _thisRepository.GetByIdAsync(model.Id);
        order.Status = model.Status;
        order.UpdateTime=DateTime.Now;
        order.LastProcessUserId = order.SendUser.Last().Id;

        // 订单完成需要记录完成信息
        if (model.Status==3)
        {
            if (string.IsNullOrEmpty(model.File) && string.IsNullOrEmpty(model.Summary))
            {
                throw new BusinessException("附件和备注必须填一项~");
            }
            
            order.AuditSummary = new CrmWocOrder.AuditSuccess()
            {
                File = model.File,
                Summary = model.Summary,
                Time = DateTime.Now
            };
            //记录添加工单日志
            await _logService.AddAsync(new CrmWocLog() { OrderId = model.Id,Status = 5});
        }

        if (model.Status==5)
        {
            //关闭，需要增加关闭原因
            order.CloseRemark = new CrmWocOrder.CloseJson()
            {
                Id = AppUtils.LoginId,
                FullName = AppUtils.LoginUser,
                Remark = model.Summary,
            };
            //记录添加工单日志
            await _logService.AddAsync(new CrmWocLog() { OrderId = model.Id,Status = 8});
        }
        if (model.Status==4)
        {
            //记录添加工单日志
            await _logService.AddAsync(new CrmWocLog() { OrderId = model.Id,Status = 7});
        }
        await _thisRepository.UpdateAsync(order);
    }


    /// <summary>
    /// 删除,支持批量
    /// </summary>
    /// 
    /// <param name="ids"></param>
    /// <returns></returns>
    [HttpDelete,UnitOfWork]
    public async Task DeleteAsync([FromBody] List<long> ids)
    {
        await _thisRepository.DeleteAsync(m=>ids.Contains(m.Id));
        await _logRepository.DeleteAsync(m => ids.Contains(m.OrderId));
    }
}
